// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.designer.ui.database.parts;

import java.util.HashMap;
import java.util.List;

import org.dengues.core.components.ENodeParameterName;
import org.dengues.core.components.NodePropertyParameter;
import org.dengues.core.property.EParameterFieldCategory;
import org.dengues.core.property.EPropertyCategory;
import org.dengues.core.sql.SqlUtils;
import org.dengues.designer.ui.database.commands.DBGefChangeSelectedCommand;
import org.dengues.designer.ui.database.commands.DBTableChangeCommand;
import org.dengues.designer.ui.database.figures.DBColumnCustomFigure;
import org.dengues.designer.ui.database.figures.DBColumnPaneFigure;
import org.dengues.designer.ui.database.figures.DBTableCustomFigure;
import org.dengues.designer.ui.database.policies.DBTableEditPolicy;
import org.dengues.designer.ui.database.policies.DBTableLayoutEditPolicy;
import org.dengues.designer.ui.database.policies.DiagramChildDirectEditPolicy;
import org.dengues.designer.ui.editors.DatabaseMultiEditor;
import org.dengues.designer.ui.editors.editmanager.DiagramChildCellEditorLocator;
import org.dengues.designer.ui.editors.editmanager.DiagramChildDirectEditManager;
import org.dengues.model.database.DBColumn;
import org.dengues.model.database.DBTable;
import org.dengues.model.database.DatabasePackage;
import org.dengues.model.database.EMFDataType;
import org.dengues.ui.metadata.CustomizeMetadataDialog;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 2007-12-12 qiang.zhang $
 * 
 */
public class DBTableEditPart extends AbstractDBGraphicalEditPart {

    /**
     * Qiang.Zhang.Adolf@gmail.com DBTableEditPart constructor comment.
     */
    public DBTableEditPart() {
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createPropertyParameters".
     * 
     * @return
     */
    @Override
    protected void createPropertyParameters() {
        NodePropertyParameter param;
        HashMap properties = getCastModel().getProperties();
        // param = new NodePropertyParameter(getCastModel());
        // param.setName(ENodeParameterName.DB_TABLE_TYPE.getName());
        // param.setValue(properties.get(param.getName()) == null ? "" : properties.get(param.getName())); //$NON-NLS-1$
        // param.setDisplayName(ENodeParameterName.DB_TABLE_TYPE.getDisplayName());
        // param.setFieldCategory(EParameterFieldCategory.COMBO);
        // param.setPropertyCategory(EPropertyCategory.PROPERTY);
        // param.setReadOnly(false);
        // param.setShow(true);
        // param.setItemValues(SqlUtils.TABLE_TYPES);
        // param.setItemDefault(SqlUtils.TABLE_TYPES[0]);
        // param.setNbRow(1);
        // propParameters.add(param);

        param = new NodePropertyParameter(getCastModel());
        param.setName(ENodeParameterName.DB_TABLE_OPERATION.getName());
        param.setValue(properties.get(param.getName()) == null ? "" : properties.get(param.getName())); //$NON-NLS-1$
        param.setDisplayName(ENodeParameterName.DB_TABLE_OPERATION.getDisplayName());
        param.setFieldCategory(EParameterFieldCategory.COMBO);
        param.setPropertyCategory(EPropertyCategory.PROPERTY);
        param.setReadOnly(false);
        param.setShow(true);
        param.setItemValues(SqlUtils.TABLE_OPERATIONS);
        param.setItemDefault(SqlUtils.TABLE_OPERATIONS[0]);
        param.setNbRow(1);
        propParameters.add(param);

        param = new NodePropertyParameter(getCastModel());
        param.setName(ENodeParameterName.DB_TABLE_COMMENT.getName());
        param.setValue(properties.get(param.getName()) == null ? "" : properties.get(param.getName())); //$NON-NLS-1$
        param.setDisplayName(ENodeParameterName.DB_TABLE_COMMENT.getDisplayName());
        param.setFieldCategory(EParameterFieldCategory.TEXT);
        param.setPropertyCategory(EPropertyCategory.PROPERTY);
        param.setReadOnly(false);
        param.setShow(true);
        param.setNbLines(4);
        param.setNbRow(2);
        propParameters.add(param);

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.designer.ui.database.parts.AbstractDBGraphicalEditPart#getCastModel()
     */
    @Override
    public DBTable getCastModel() {
        return ((DBTable) getModel());
    }

    private DBTableCustomFigure customTableFigure;

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
     */
    @Override
    protected IFigure createFigure() {
        createNodeParameters();
        customTableFigure = new DBTableCustomFigure(getCastModel());
        return customTableFigure;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getPrimaryFigure".
     * 
     * @return
     */
    public DBTableCustomFigure getPrimaryFigure() {
        return customTableFigure;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#addChildVisual(org.eclipse.gef.EditPart, int)
     */
    @Override
    protected void addChildVisual(EditPart childEditPart, int index) {
        if (childEditPart instanceof DBColumnEditPart) {
            super.addChildVisual(childEditPart, -1);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
     */
    @Override
    protected void createEditPolicies() {
        installEditPolicy(EditPolicy.LAYOUT_ROLE, new DBTableLayoutEditPolicy());
        installEditPolicy(EditPolicy.COMPONENT_ROLE, new DBTableEditPolicy());
        installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new DiagramChildDirectEditPolicy());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#getModelChildren()
     */
    @Override
    protected List<DBColumn> getModelChildren() {
        return ((DBTable) getModel()).getColumns();
    }

    private DiagramChildDirectEditManager directEditManager;

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
     */
    public void notifyChanged(Notification notification) {
        int type = notification.getEventType();
        int id = notification.getFeatureID(DatabasePackage.class);
        switch (type) {
        case Notification.SET:
            switch (id) {
            case DatabasePackage.DB_TABLE__X:
            case DatabasePackage.DB_TABLE__Y:
            case DatabasePackage.DB_TABLE__HEIGHT:
            case DatabasePackage.DB_TABLE__WIDTH:
            case DatabasePackage.DB_TABLE__NAME:
                refreshVisuals();
                break;
            case DatabasePackage.DIAGRAM_CHILD__SELECTED:
                List children2 = getChildren();
                for (Object object : children2) {
                    if (object instanceof DBColumnEditPart) {
                        DBColumnEditPart columnEditPart = (DBColumnEditPart) object;
                        DBColumnCustomFigure columnFigure = (DBColumnCustomFigure) columnEditPart.getFigure();
                        getCommandStack().execute(
                                new DBGefChangeSelectedCommand(columnEditPart.getCastModel(), getCastModel().isSelected(),
                                        EMFDataType.QUERY));
                        columnFigure.setIsSelected(getCastModel().isSelected());
                    }
                }
                break;
            }
        }
        if (type == Notification.ADD || type == Notification.REMOVE) {
            refreshChildren();
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#refreshVisuals()
     */
    @Override
    protected void refreshVisuals() {
        Rectangle bounds = new Rectangle(getCastModel().getX(), getCastModel().getY(), getCastModel().getWidth(), getCastModel()
                .getHeight());
        customTableFigure.getTableName().setText(getCastModel().getName());
        ((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), bounds);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractEditPart#performRequest(org.eclipse.gef.Request)
     */
    @Override
    public void performRequest(Request req) {

        IWorkbenchPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
        if (part instanceof DatabaseMultiEditor) {
            CommandStack cmdStack = (CommandStack) part.getAdapter(CommandStack.class);
            if (RequestConstants.REQ_OPEN.equals(req.getType())) {
                DBTable castModel = getCastModel();
                CustomizeMetadataDialog dialog = new CustomizeMetadataDialog(Display.getCurrent().getActiveShell(), castModel);
                dialog.open();
                List<DBColumn> dbColumns = dialog.getDbColumns();
                if (dbColumns != null) {
                    DBTableChangeCommand command = new DBTableChangeCommand(castModel, dbColumns);
                    cmdStack.execute(command);
                    refreshChildren();
                }
            }
            if (RequestConstants.REQ_DIRECT_EDIT.equals(req.getType())) {
                if (directEditManager == null) {
                    DBTableCustomFigure noteFigure = (DBTableCustomFigure) getFigure();
                    directEditManager = new DiagramChildDirectEditManager(this, TextCellEditor.class,
                            new DiagramChildCellEditorLocator(noteFigure));
                }
                directEditManager.show();
            }
        }
        super.performRequest(req);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getContentPane()
     */
    @Override
    public IFigure getContentPane() {
        DBColumnPaneFigure panel = ((DBTableCustomFigure) getFigure()).getColumnPaneFigure();
        return panel;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getCustomTableFigure".
     * 
     * @return
     */
    public DBTableCustomFigure getCustomTableFigure() {
        return this.customTableFigure;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.designer.ui.database.parts.AbstractDBGraphicalEditPart#createMainParameters()
     */
    @Override
    protected void createMainParameters() {
        NodePropertyParameter param;
        HashMap properties = getCastModel().getProperties();
        param = new NodePropertyParameter(getCastModel());
        param.setName(ENodeParameterName.DB_TABLE_NAME.getName());
        param.setValue(getCastModel().getName());
        param.setDisplayName(ENodeParameterName.DB_TABLE_NAME.getDisplayName());
        param.setFieldCategory(EParameterFieldCategory.TEXT);
        param.setPropertyCategory(EPropertyCategory.MAIN);
        param.setReadOnly(true);
        param.setShow(true);
        param.setNbRow(1);
        propParameters.add(param);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getCommandStack".
     * 
     * @return
     */
    public CommandStack getCommandStack() {
        EditPart parent2 = getParent();
        if (parent2 instanceof DBDiagramEditPart) {
            return ((DBDiagramEditPart) parent2).getCommandStack();
        }
        return null;
    }
}
